#include "cm_uart.h"
#include "cm_demo_uart.h"
#include "cm_iomux.h"
#include "test_gpio.h"
#include "cm_pm.h"


static cm_gpio_num_e pin = 0;
static cm_gpio_num_e gpio_num = 0;
static int dis_inter_ret = -1;
static int irq_count = 0;
static void pin_irq_callback(void)
{
    // cm_demo_printf("GPIO INTERRUPT!!!!!!!!");
	// cm_demo_printf("gpio:%d\n",gpio_num);
    // cm_demo_printf("gpio irq_dis ret:%d\n", cm_gpio_interrupt_disable(gpio_num));
    irq_count++;
    dis_inter_ret = cm_gpio_interrupt_disable(gpio_num);
    //cm_pm_work_lock();
}


/*
指令：
CM:GPIO_OPERATION:INIT:[GPIO序号]:[引脚号]:[功能号]:[输入或输出方向]:[上下拉方式]
CM:GPIO_OPERATION:DEINIT:[GPIO序号]
CM:GPIO_OPERATION:WRITE:[GPIO序号]
CM:GPIO_OPERATION:READ:[GPIO序号]
CM:GPIO_OPERATION:SET_DIR:[GPIO序号]:[输入或输出方向]
CM:GPIO_OPERATION:GET_DIR:[GPIO序号]
CM:GPIO_OPERATION:SET_PULL:[GPIO序号]:[上下拉方式]
CM:GPIO_OPERATION:GET_PULL:[GPIO序号]
CM:GPIO_OPERATION:IRQ_ENABLE:[GPIO序号]:[中断方式]    //使能中断
CM:GPIO_OPERATION:IRQ_REG:[GPIO序号]:[中断方式]    //中断注册
CM:GPIO_OPERATION:IRQ_DISENABLE:[GPIO序号]         //  关闭中断
CM:GPIO_OPERATION:IRQ_CB_PRINT    //查看是否进入中断回调函数

*/

void cm_test_gpio_operation(unsigned char *cmd[],int len)
{
    if(0 == strcmp("INIT",cmd[2]))
    {
        cm_gpio_cfg_t cfg = {0};
        gpio_num = atoi(cmd[3]);
        cm_iomux_pin_e pin = (cm_iomux_pin_e)atoi(cmd[4]);
        cm_iomux_func_e fun = (cm_iomux_func_e)atoi(cmd[5]);
        cm_demo_printf("gpio set_pin_func ret:%d\n",cm_iomux_set_pin_func(pin, fun));//初始化之前一定要先设置引脚复用
        cm_iomux_func_e fun1 = 0; 
        cm_iomux_get_pin_func(pin,&fun1);
        if(fun1 !=fun)
        {
            cm_demo_printf("gpio_%d set iomux failed\n", pin);
            return;
        }
        cfg.direction = (cm_gpio_direction_e)atoi(cmd[6]);
        cfg.pull = (cm_gpio_pull_e)atoi(cmd[7]);
        int32_t gpio_init = cm_gpio_init(gpio_num, &cfg);
        cm_demo_printf("gpio init ret:%d\n", gpio_init);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,gpio_init,cm_gpio_init);
    }
    else if(0 == strcmp("DEINIT",cmd[2]))
    {
        gpio_num = atoi(cmd[3]);
        int32_t gpio_deinit = cm_gpio_deinit(gpio_num);
        cm_demo_printf("cm_gpio_deinit ret:%d\n", gpio_deinit);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,gpio_deinit,cm_gpio_deinit);
    }
    else if(0 == strcmp("WRITE",cmd[2]))
    {
        gpio_num = atoi(cmd[3]);
        cm_gpio_level_e level = 0;
        cm_demo_printf("cm_gpio_set_level ret:%d\n",cm_gpio_set_level(gpio_num,level));
        osDelay(5);
        level = 1;
        cm_demo_printf("cm_gpio_set_level ret:%d\n",cm_gpio_set_level(gpio_num,level));
        osDelay(5);
        level = 0;
        cm_demo_printf("cm_gpio_set_level ret:%d\n",cm_gpio_set_level(gpio_num,level));
        osDelay(5);
        level = 1;
        int32_t set_level = cm_gpio_set_level(gpio_num,level);
        cm_demo_printf("cm_gpio_set_level ret:%d\n",set_level);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,set_level,cm_gpio_set_level);
        osDelay(5);
    }
    else if(0 == strcmp("READ",cmd[2]))
    {
        gpio_num = atoi(cmd[3]);
        cm_gpio_level_e level = 0;
        int32_t get_level = cm_gpio_get_level(gpio_num,&level);
        cm_demo_printf("cm_gpio_get_level ret:%d\n", get_level);
        cm_demo_printf("read level:%d\n",level);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,get_level,cm_gpio_get_level);
        OCTEST_EXPECT_GREATER_OR_EQUAL_INT32(0,get_level);
    }
    else if(0 == strcmp("CONTROL",cmd[2]))
    {
        gpio_num = atoi(cmd[3]);
        cm_gpio_cmd_e gpio_cmd = (cm_gpio_cmd_e)atoi(cmd[4]);
        int32_t arg = atoi(cmd[5]);
        //  *  cmd = \ref GPIO_CMD_SET_PULL, arg传入\ref cm_gpio_pull_e *               \n
        //  *  cmd = \ref GPIO_CMD_GET_PULL, arg传入\ref cm_gpio_pull_e *               \n
        //  *  cmd = \ref GPIO_CMD_SET_LEVEL, arg传入\ref cm_gpio_level_e *             \n
        //  *  cmd = \ref GPIO_CMD_GET_LEVEL, arg传入\ref cm_gpio_level_e *             \n
        //  *  cmd = \ref GPIO_CMD_SET_DIRECTION, arg传入\ref cm_gpio_direction_e *     \n
        //  *  cmd = \ref GPIO_CMD_GET_DIRECTION, arg传入\ref cm_gpio_direction_e *     \n
        //  */
        int32_t gpio_ioctl = cm_gpio_ioctl(gpio_num,  gpio_cmd, &arg);
        cm_demo_printf("gpio cm_gpio_ioctl ret:%d\n", gpio_ioctl);
        cm_demo_printf("gpio ioctl arg:%d\n",arg);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,gpio_ioctl,cm_gpio_ioctl);
    }else if(0 == strcmp("IRQ_DISABLE",cmd[2]))
    {
        gpio_num = (cm_gpio_num_e)atoi(cmd[3]);
        int32_t interrupt_disable = cm_gpio_interrupt_disable( gpio_num);
        cm_demo_printf("gpio irq_dis ret:%d\n",interrupt_disable);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,interrupt_disable,cm_gpio_interrupt_disable);
    }else if(0 == strcmp("IRQ_REG",cmd[2]))
    {
        gpio_num = (cm_gpio_num_e)atoi(cmd[3]);
        int32_t interrupt_register = cm_gpio_interrupt_register(gpio_num, pin_irq_callback);
        cm_demo_printf("cm_gpio_interrupt_register ret:%d\n", interrupt_register);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,interrupt_register,cm_gpio_interrupt_register);
    }else if(0 == strcmp("IRQ_ENABLE",cmd[2]))
    {
        dis_inter_ret = -1;
        gpio_num = (cm_gpio_num_e)atoi(cmd[3]);
        cm_gpio_interrupt_e intr_mode = (cm_gpio_interrupt_e)atoi(cmd[4]);
        int32_t interrupt_enable = cm_gpio_interrupt_enable(gpio_num,intr_mode);
        cm_demo_printf("cm_gpio_interrupt_enable ret:%d\n", interrupt_enable);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,interrupt_enable,cm_gpio_interrupt_enable);
    }
    else if(0 == strcmp("IRQ_CB_PRINT",cmd[2]))
    {
        cm_demo_printf("gpio num:%d, irq_dis ret:%d, irq_count:%d\n",gpio_num,dis_inter_ret,irq_count);
    }
    else if(0 == strcmp("GET_DIR",cmd[2]))
    {
        gpio_num = (cm_gpio_num_e)atoi(cmd[3]);
        cm_gpio_direction_e *dir = (cm_gpio_direction_e*)malloc(sizeof(int32_t));
        //cm_gpio_direction_e dir = -1;
        if(NULL == dir)
        {
            cm_demo_printf("malloc fail!\n");
            return;
        }
        int32_t get_direction = cm_gpio_get_direction( gpio_num, dir);
        cm_demo_printf("gpio get_direction ret:%d\n",get_direction);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,get_direction,cm_gpio_get_direction);
        cm_demo_printf("get direction:%d\n",*dir);
        free(dir);
    }else if(0 == strcmp("SET_DIR",cmd[2]))
    {
        gpio_num = atoi(cmd[3]);
        //cm_iomux_pin_e pin = (cm_iomux_pin_e)atoi(cmd[4]);
        //cm_iomux_func_e fun = (cm_iomux_func_e)atoi(cmd[5]);
        //cm_demo_printf("pin:%d, fun:%d\n",pin,fun);
       cm_gpio_direction_e dir = atoi(cmd[4]);

       // cm_gpio_cfg_t cfg = {0};

       // cm_demo_printf("gpio set_pin_func ret:%d\n", cm_iomux_set_pin_func(pin, fun));//初始化之前一定要先设置引脚复用
      //  cm_iomux_func_e fun1 = 0; 
       // cm_iomux_get_pin_func(pin,&fun1);
       // if(fun1 !=fun)
        //{
       //     cm_demo_printf("gpio_%d set iomux failed\n", pin);
       //     return;
       // }

        //cm_demo_printf("gpio init ret:%d\n", cm_gpio_init(gpio_num, &cfg));
        int32_t set_direction = cm_gpio_set_direction(gpio_num,dir);
        cm_demo_printf("gpio cm_gpio_set_direction ret:%d\n",set_direction);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,set_direction,cm_gpio_set_direction);
    }else if(0 == strcmp("SET_PULL",cmd[2]))
    {
           gpio_num = atoi(cmd[3]);
           // cm_iomux_pin_e pin = (cm_iomux_pin_e)atoi(cmd[4]);
            //cm_iomux_func_e fun = (cm_iomux_func_e)atoi(cmd[5]);
            cm_gpio_pull_e type = (cm_gpio_pull_e)atoi(cmd[4]);
            //cm_demo_printf("gpio set_pin_func ret:%d\n", cm_iomux_set_pin_func(pin, fun));//初始化之前一定要先设置引脚复用
            //cm_iomux_func_e fun1 = 0; 
           // cm_iomux_get_pin_func(pin,&fun1);
           // if(fun1 !=fun)
           // {
            //    cm_demo_printf("gpio_%d set iomux failed\n", pin);
            //    return;
            //}
            //cm_gpio_cfg_t cfg = {0};
            //cm_demo_printf("gpio init ret:%d\n", cm_gpio_init(gpio_num, &cfg));
        int32_t gpio_set_pull = cm_gpio_set_pull( gpio_num,  type);
        cm_demo_printf("gpio set_pull ret:%d\n",gpio_set_pull);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,gpio_set_pull,cm_gpio_set_pull);
    }
    else if(0 == strcmp("GET_PULL",cmd[2]))
    {
        gpio_num = (cm_gpio_num_e)atoi(cmd[3]);
        cm_gpio_pull_e *type = (cm_gpio_pull_e*)malloc(sizeof(int32_t));
        if(NULL == type)
        {
            cm_demo_printf("malloc fail!\n");
            return;
        }
        int32_t gpio_get_pull = cm_gpio_get_pull(gpio_num, type);
        cm_demo_printf("gpio get_pull ret:%d\n",gpio_get_pull);
        OCTEST_FUNC_EXPECT_EQUAL_INT32(0,gpio_get_pull,cm_gpio_get_pull);
        cm_demo_printf("gpio get pull type:%d\n",*type);
        free(type);
    }else 
    {
        cm_demo_printf("param error!\n");
    } 
}